/**
 * 
 */
package fr.toussna.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.jdbc.core.RowMapper;

import fr.toussna.entity.Article;
import fr.toussna.entity.Comment;
import fr.toussna.entity.DomainEntity;

/**
 * Cette classe est une spécialisation de la classe {@link AbstractDAO}, elle
 * implémente toutes les méthodes abstraite de la classe mère. Elle spécifie les
 * requêtes Sql pour l'entité {@link Comment} et rajoutes des méthodes adaptées
 * a la classe Comment.
 * 
 * C'est dans cette classe qu'on implémente les algorithmes pour compléter le
 * design pattern Template. On utilise le {@link RowMapper} de Spring JDBC pour
 * simplifier le Mapping objet relationnel.
 * 
 * @author My
 * @version 2.0
 * 
 */
public class CommentDAO extends AbstractDAO {

	private static final Log	LOGGER	= LogFactory.getLog(CommentDAO.class
	                                            .getName());

	// **********************************
	// * Attributs *
	// **********************************
	/**
	 * Nom de la table dans la base
	 */
	private static final String	TABLE	= "COMMENT";

	/**
	 * Colonne de la table dans la base
	 */
	private static final String	COLUMNS	= "ARTICLEID, TITLE, AUTOR, CONTENT";

	// **************************************
	// * Methodes specialles a cette classe *
	// **************************************
	/**
	 * Cette méthode est spécifique aux entités Comment, elle permet de
	 * sélectionner les commentaires du même article.
	 * 
	 * @param article
	 *            L'article
	 * @return La liste des commentaires du mem article.
	 */
	public List<DomainEntity> selectAllByArticle(Article article) {
		List<DomainEntity> list = query(getSelectAllByArticleSqlStatement(),
		        new Object[] { article.getId() }, getDomainEntityRowMapper());
		if (LOGGER.isDebugEnabled()) {
			LOGGER.debug("Selectin All Comments by article using statement: "
			        + getSelectAllSqlStatement() + "\n Received data: "
			        + list.toString());
		}
		return list;
	}

	// **********************************
	// * Methodes heritees *
	// **********************************

	/*
	 * (non-Javadoc)
	 * 
	 * @see fr.toussna.dao.AbstractDAO#getSelectSqlStatement()
	 */
	@Override
	protected String getSelectSqlStatement() {
		String sql = "SELECT * FROM " + TABLE + " WHERE ID= ?";
		return sql;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see fr.toussna.dao.AbstractDAO#getInsertSqlStatement()
	 */
	@Override
	protected String getInsertSqlStatement() {
		// ARTICLEID, TITLE, AUTOR, CONTENT
		String sql = "INSERT INTO " + TABLE + " (" + COLUMNS
		        + ") VALUES (?,?,?,?)";
		return sql;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see fr.toussna.dao.AbstractDAO#getUpdateSqlStatement()
	 */
	@Override
	protected String getUpdateSqlStatement() {
		// ARTICLEID, TITLE, AUTOR, CONTENT
		String sql = "UPDATE "
		        + TABLE
		        + " SET ARTICLEID= ?, TITLE= ?, AUTOR= ?, CONTENT= ?  WHERE ID= ?";
		return sql;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see fr.toussna.dao.AbstractDAO#getDeleteSqlStatement()
	 */
	@Override
	protected String getDeleteSqlStatement() {
		String sql = "DELETE FROM " + TABLE + " WHERE ID= ?";
		return sql;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see fr.toussna.dao.AbstractDAO#getSelectAllSqlStatement()
	 */
	@Override
	protected String getSelectAllSqlStatement() {
		String sql = "SELECT * FROM " + TABLE;
		return sql;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see fr.toussna.dao.AbstractDAO#getSelectByKeySqlStatement()
	 */
	@Override
	protected String getSelectByKeySqlStatement(String key) {
		String sql = "SELECT * FROM  " + TABLE
		        + " WHERE  CONTENT LIKE '%"+key+"%' OR TITLE LIKE '%"+key+"%' OR AUTOR LIKE '%"+key+"%'";
		return sql;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see fr.toussna.dao.AbstractDAO#getDomainEntityRowMapper()
	 */
	@Override
	protected RowMapper<DomainEntity> getDomainEntityRowMapper() {
		return new RowMapper<DomainEntity>() {

			@Override
			public Comment mapRow(ResultSet rs, int rowNum) throws SQLException {
				Comment comment = new Comment();
				// ARTICLEID, TITLE, AUTOR, CONTENT
				comment.setId(rs.getLong("id"));
				comment.setArticle(new Article(rs.getLong("articleid")));
				comment.setTitle(rs.getString("title"));
				comment.setAutor(rs.getString("autor"));
				comment.setContent(rs.getString("content"));

				if (LOGGER.isDebugEnabled()) {
					LOGGER.debug("Mapped data to entity: " + comment.toString());
				}

				return comment;
			}
		};
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * fr.toussna.dao.AbstractDAO#getDomainEntityData(fr.toussna.entity.DomainEntity
	 * )
	 */
	@Override
	protected Object[] getDomainEntityData(DomainEntity entity) {
		Comment comment = (Comment) entity;
		// ARTICLEID, TITLE, AUTOR, CONTENT
		if (comment.getId() > 0) {
			Object[] obj = new Object[] { comment.getArticle().getId(),
			        comment.getTitle(), comment.getAutor(), comment.getContent(), comment.getId() };
			if (LOGGER.isDebugEnabled()) {
				LOGGER.debug("Mapped entity to row data: "
				        + Arrays.toString(obj));
			}
			return obj;
		} else {
			Object[] obj = new Object[] { comment.getArticle().getId(),
			        comment.getTitle(), comment.getAutor(), comment.getContent() };
			if (LOGGER.isDebugEnabled()) {
				LOGGER.debug("Mapped entity to row data: "
				        + Arrays.toString(obj));
			}
			return obj;
		}
	}

	// **********************************
	// * Private Methodes *
	// **********************************
	/**
	 * @return la requête  sql 
	 */
	private String getSelectAllByArticleSqlStatement() {
		String sql = "SELECT * FROM  " + TABLE + " WHERE ARTICLEID= ? ";
		return sql;
	}

}
